#include "mtwidget.h"

MTWidget::MTWidget(QWidget * parent):QGraphicsWidget(parent)
{
    this->rotates = false;
    this->isZoomable = false;
    this->isDraggable = false;
}
//some useful functions
qreal sqr (qreal a){
    return a*a;
}
qreal pointDistance(QPointF a, QPointF b){
    return sqrt((sqr(a.x() - b.x()) + sqr(a.y() - b.y())));
}

void MTWidget::rotateZoomMove(int touchID, QPointF pos){

        // some default values, in case we dont calculate them,
        qreal rotation = 0;
        qreal scale = 1;
        QPointF trans = QPointF(0,0);

        //p1_start is where was the point
        //p1_now is where is the point now!
        QPointF p1_start = this->touches.value(touchID);
        QPointF p1_now   = pos;
        QPointF rotationPoint = QPointF(0,0);

        // if we have a second point, do the scale/rotate thing
        int second_touch = this->findSecondTouch(touchID);

        if (second_touch!= -1){
            //p2 is the point that is fixed when p1 is moving
            QPointF p2_start = this->touches.value(second_touch);
            QPointF p2_now   = this->touches.value(second_touch);

            // compute scale factor

            qreal old_dist = pointDistance(p1_start, p2_start);
            qreal new_dist = pointDistance(p1_now ,p2_now);
            scale = new_dist/old_dist;
            this->scale(scale,scale);
            if (scale!=1) emit zoomed();


            // compute rotation angle
            QLineF old_line = QLineF(QPoint(), p1_start - p2_start);
            QLineF new_line = QLineF(QPoint(), p1_now - p2_now);
            rotation = -1.0 * old_line.angleTo(new_line);
            qDebug() << rotation;
            qreal x = (p1_start.x());
            qreal y = (p1_start.y());
            this->setTransform(QTransform().translate(x, y).rotate(rotation).translate(-x, -y));
            if (rotation!=0) emit rotated();

        }
        else {
            trans = p1_now - p1_start;
            this->setPos(this->pos()+trans);
        }

        QRectF r = this->sceneBoundingRect();
        double w = r.width();
        double h = r.height();
        qreal x = rotationPoint.x();
        qreal y = rotationPoint.y();
        //;
        // save new position of the current touch
        this->touches[touchID] = pos;
}


int MTWidget::findSecondTouch(int touchID)
{
        QMapIterator<int, QPointF> i(this->touches);
        while (i.hasNext()) {
            i.next();
            int tID = i.key();
            QPointF p;
            if (this->touches.contains(tID)){
                p = touches.value(tID);
                if(this->contains(p) and tID!= touchID)
                    return tID;
            }
        }
        return -1;
}

bool MTWidget::onTouchDown(int touchId, QPointF pos){
    if(this->touches.contains(touchId))
        return false;
    // Adds only if it's a new point
    this->touches[touchId] = pos;
    return true;

    }

bool MTWidget::onTouchUp(int touchId, QPointF pos){
    if(!this->touches.contains(touchId))
        return false;
    this->touches.remove(touchId);
    return true;
}

bool MTWidget::onTouchMove(int touchId, QPointF pos){
    // If it wasn't on me or isn't on the list.
    if(!(this->contains(pos)or this->touches.count(touchId)>0))
            return false;
    // If a touch is already registered
    if (this->touches.count(touchId)>0){
        this->rotateZoomMove(touchId, pos);
        return true;
    }
    return this->touches.contains(touchId);
}

void MTWidget::onTouch(int touchId, double x, double y, int type){

    switch (type){
        case TOUCHDOWN:
            this->onTouchDown(touchId, QPointF(x,y));
            break;
        case TOUCHUP:
            this->onTouchUp(touchId, QPointF(x,y));
            break;
        case TOUCHMOVE:
            this->onTouchMove(touchId, QPointF(x,y));
            break;
        }
}

void MTWidget::mouseMoveEvent(QMouseEvent * event)
{}
